package com.ias.system.user.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ias.system.user.entity.User;
import com.ias.system.user.service.UserService;
import com.ias.system.user.service.impl.UserServiceImpl;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import com.ias.common.result.Result;
import com.ias.common.result.PageResult;
import com.ias.common.utils.page.PageUtil;
import com.ias.common.request.PageRequest;
import jakarta.validation.Valid;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户管理控制器
 * 演示baomidou动态数据源的使用
 * 
 * @author IAS Team
 * @since 1.0.0
 */
@Slf4j
@RestController
@RequestMapping("/users")
@RequiredArgsConstructor
@Tag(name = "用户管理", description = "用户管理相关接口")
public class UserController {

    private final UserService userService;
    private final UserServiceImpl userServiceImpl;

    /**
     * 分页查询用户列表 - 演示从库查询
     * 基于MyBatis-Plus 3.5.9优化，使用标准分页参数
     */
    @GetMapping("/page")
    @Operation(summary = "分页查询用户", description = "使用从库查询用户列表，支持关键词搜索")
    public Result<PageResult<User>> getUserPage(@Valid PageRequest pageRequest) {
        
        log.info("分页查询用户，页码：{}，每页大小：{}，关键词：{}", 
                pageRequest.getCurrentSafe(), pageRequest.getSizeSafe(), pageRequest.getKeywordSafe());
        
        Page<User> page = new Page<>(pageRequest.getCurrentSafe(), pageRequest.getSizeSafe());
        IPage<User> result = userService.selectUserPage(page, pageRequest.getKeywordSafe());
        
        // 转换为标准分页结果
        PageResult<User> pageResult = PageUtil.convertFromIPage(result);

        return Result.success(pageResult);
    }

    /**
     * 分页查询用户列表 - 兼容原有接口
     * 保持向后兼容性
     */
    @GetMapping("/page/legacy")
    @Operation(summary = "分页查询用户(兼容接口)", description = "兼容原有的分页查询接口")
    public Result<PageResult<User>> getUserPageLegacy(
            @Parameter(description = "页码", example = "1") @RequestParam(defaultValue = "1" ,name="current") Long current,
            @Parameter(description = "每页大小", example = "10") @RequestParam(defaultValue = "10",name="size") Long size,
            @Parameter(description = "搜索关键词") @RequestParam(required = false,name="keyword") String keyword) {
        
        log.info("兼容接口 - 分页查询用户，页码：{}，每页大小：{}，关键词：{}", current, size, keyword);
        
        // 创建分页请求对象
        PageRequest pageRequest = new PageRequest();
        pageRequest.setCurrent(current);
        pageRequest.setSize(size);
        pageRequest.setKeyword(keyword);
        
        return getUserPage(pageRequest);
    }

    /**
     * 根据ID查询用户详情 - 演示从库查询
     */
    @GetMapping("/{id}")
    @Operation(summary = "查询用户详情", description = "使用从库根据ID查询用户详情")
    public ResponseEntity<Map<String, Object>> getUserById(
            @Parameter(description = "用户ID") @PathVariable Long id) {
        
        log.info("查询用户详情，ID：{}", id);
        
        User user = userService.getById(id);
        
        Map<String, Object> response = new HashMap<>();
        if (user != null) {
            response.put("code", 200);
            response.put("message", "查询成功");
            response.put("data", user);
        } else {
            response.put("code", 404);
            response.put("message", "用户不存在");
            response.put("data", null);
        }
        response.put("dataSource", "slave");
        
        return ResponseEntity.ok(response);
    }

    /**
     * 根据用户名查询用户 - 演示从库查询
     */
    @GetMapping("/username/{username}")
    @Operation(summary = "根据用户名查询用户", description = "使用从库根据用户名查询用户")
    public ResponseEntity<Map<String, Object>> getUserByUsername(
            @Parameter(description = "用户名") @PathVariable String username) {
        
        log.info("根据用户名查询用户：{}", username);
        
        User user = userServiceImpl.getUserByUsername(username);
        
        Map<String, Object> response = new HashMap<>();
        if (user != null) {
            response.put("code", 200);
            response.put("message", "查询成功");
            response.put("data", user);
        } else {
            response.put("code", 404);
            response.put("message", "用户不存在");
            response.put("data", null);
        }
        response.put("dataSource", "slave");
        
        return ResponseEntity.ok(response);
    }

    /**
     * 统计用户数量 - 演示从库查询
     */
    @GetMapping("/count")
    @Operation(summary = "统计用户数量", description = "使用从库统计用户总数")
    public ResponseEntity<Map<String, Object>> countUsers() {
        
        log.info("统计用户数量");
        
        long count = userServiceImpl.countUsers();
        
        Map<String, Object> response = new HashMap<>();
        response.put("code", 200);
        response.put("message", "统计成功");
        response.put("data", count);
        response.put("dataSource", "slave");
        
        return ResponseEntity.ok(response);
    }

    /**
     * 创建用户 - 演示主库写入
     */
    @PostMapping
    @Operation(summary = "创建用户", description = "使用主库创建新用户")
    public ResponseEntity<Map<String, Object>> createUser(@Valid @RequestBody User user) {
        
        log.info("创建用户：{}", user.getUsername());
        
        // 设置默认值
        if (user.getStatus() == null) {
            user.setStatus(1);
        }
        if (user.getGender() == null) {
            user.setGender(1);
        }
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        
        boolean result = userService.save(user);
        
        Map<String, Object> response = new HashMap<>();
        if (result) {
            response.put("code", 200);
            response.put("message", "创建成功");
            response.put("data", user);
        } else {
            response.put("code", 500);
            response.put("message", "创建失败");
            response.put("data", null);
        }
        response.put("dataSource", "master");
        
        return ResponseEntity.ok(response);
    }

    /**
     * 更新用户 - 演示主库更新
     */
    @PutMapping("/{id}")
    @Operation(summary = "更新用户", description = "使用主库更新用户信息")
    public ResponseEntity<Map<String, Object>> updateUser(
            @Parameter(description = "用户ID") @PathVariable Long id,
            @Valid @RequestBody User user) {
        
        log.info("更新用户，ID：{}", id);
        
        user.setId(id);
        user.setUpdateTime(LocalDateTime.now());
        
        boolean result = userService.updateById(user);
        
        Map<String, Object> response = new HashMap<>();
        if (result) {
            response.put("code", 200);
            response.put("message", "更新成功");
            response.put("data", user);
        } else {
            response.put("code", 500);
            response.put("message", "更新失败");
            response.put("data", null);
        }
        response.put("dataSource", "master");
        
        return ResponseEntity.ok(response);
    }

    /**
     * 删除用户 - 演示主库删除
     */
    @DeleteMapping("/{id}")
    @Operation(summary = "删除用户", description = "使用主库删除用户（逻辑删除）")
    public ResponseEntity<Map<String, Object>> deleteUser(
            @Parameter(description = "用户ID") @PathVariable Long id) {
        
        log.info("删除用户，ID：{}", id);
        
        boolean result = userServiceImpl.removeById(id);
        
        Map<String, Object> response = new HashMap<>();
        if (result) {
            response.put("code", 200);
            response.put("message", "删除成功");
        } else {
            response.put("code", 500);
            response.put("message", "删除失败");
        }
        response.put("dataSource", "master");
        
        return ResponseEntity.ok(response);
    }

    /**
     * 重置用户密码 - 演示主库更新
     */
    @PutMapping("/{id}/reset-password")
    @Operation(summary = "重置用户密码", description = "使用主库重置用户密码为默认密码123456")
    public ResponseEntity<Map<String, Object>> resetPassword(
            @Parameter(description = "用户ID") @PathVariable Long id) {
        
        log.info("重置用户密码，ID：{}", id);
        
        boolean result = userService.resetPassword(id);
        
        Map<String, Object> response = new HashMap<>();
        if (result) {
            response.put("code", 200);
            response.put("message", "密码重置成功，新密码：123456");
        } else {
            response.put("code", 500);
            response.put("message", "密码重置失败");
        }
        response.put("dataSource", "master");
        
        return ResponseEntity.ok(response);
    }

    /**
     * 修改密码 - 演示主库更新
     */
    @PutMapping("/change-password")
    @Operation(summary = "修改密码", description = "使用主库修改当前用户密码")
    public ResponseEntity<Map<String, Object>> changePassword(
            @Parameter(description = "旧密码") @RequestParam String oldPassword,
            @Parameter(description = "新密码") @RequestParam String newPassword) {
        
        log.info("修改用户密码");
        
        boolean result = userService.changePassword(oldPassword, newPassword);
        
        Map<String, Object> response = new HashMap<>();
        if (result) {
            response.put("code", 200);
            response.put("message", "密码修改成功");
        } else {
            response.put("code", 400);
            response.put("message", "密码修改失败，请检查旧密码是否正确");
        }
        response.put("dataSource", "master");
        
        return ResponseEntity.ok(response);
    }

    /**
     * 批量创建用户 - 演示主库批量写入
     */
    @PostMapping("/batch")
    @Operation(summary = "批量创建用户", description = "使用主库批量创建用户")
    public ResponseEntity<Map<String, Object>> batchCreateUsers() {
        
        log.info("批量创建测试用户");
        
        List<User> users = new ArrayList<>();
        for (int i = 1; i <= 5; i++) {
            User user = new User();
            user.setUsername("batch_user_" + i);
            user.setPassword("123456");
            user.setRealName("批量用户" + i);
            user.setPhone("1380013" + String.format("%04d", 8000 + i));
            user.setEmail("batch_user_" + i + "@ias.com");
            user.setGender(i % 2 + 1);
            user.setStatus(1);
            user.setDeptId((long) (i % 3 + 1));
            user.setCreateTime(LocalDateTime.now());
            user.setUpdateTime(LocalDateTime.now());
            users.add(user);
        }
        
        boolean result = userServiceImpl.saveBatch(users);
        
        Map<String, Object> response = new HashMap<>();
        if (result) {
            response.put("code", 200);
            response.put("message", "批量创建成功");
            response.put("data", users);
        } else {
            response.put("code", 500);
            response.put("message", "批量创建失败");
            response.put("data", null);
        }
        response.put("dataSource", "master");
        
        return ResponseEntity.ok(response);
    }

    /**
     * 数据源测试接口 - 演示读写分离
     */
    @GetMapping("/test-datasource")
    @Operation(summary = "测试数据源", description = "测试读写分离，先查询从库，再写入主库，最后再查询从库")
    public ResponseEntity<Map<String, Object>> testDataSource() {
        
        log.info("开始测试数据源读写分离");
        
        Map<String, Object> testResult = new HashMap<>();
        
        // 1. 先从从库查询用户数量
        long countBefore = userServiceImpl.countUsers();
        testResult.put("countBefore", countBefore);
        testResult.put("step1", "从库查询用户数量：" + countBefore);
        
        // 2. 向主库插入一个测试用户
        User testUser = new User();
        testUser.setUsername("test_" + System.currentTimeMillis());
        testUser.setPassword("123456");
        testUser.setRealName("数据源测试用户");
        testUser.setPhone("13800138999");
        testUser.setEmail("test@ias.com");
        testUser.setGender(1);
        testUser.setStatus(1);
        testUser.setDeptId(1L);
        testUser.setCreateTime(LocalDateTime.now());
        testUser.setUpdateTime(LocalDateTime.now());
        
        boolean saveResult = userService.save(testUser);
        testResult.put("saveResult", saveResult);
        testResult.put("step2", "主库插入用户：" + (saveResult ? "成功" : "失败"));
        testResult.put("newUserId", testUser.getId());
        
        // 3. 再从从库查询用户数量（可能因为主从延迟，数量暂时不变）
        long countAfter = userServiceImpl.countUsers();
        testResult.put("countAfter", countAfter);
        testResult.put("step3", "从库查询用户数量：" + countAfter);
        
        // 4. 从主库查询刚插入的用户（应该能查到）
        User userFromMaster = userService.getById(testUser.getId());
        testResult.put("step4", "主库查询新用户：" + (userFromMaster != null ? "成功" : "失败"));
        
        Map<String, Object> response = new HashMap<>();
        response.put("code", 200);
        response.put("message", "数据源测试完成");
        response.put("data", testResult);
        response.put("description", "此测试演示了读写分离：查询使用从库(slave)，写入使用主库(master)");
        
        return ResponseEntity.ok(response);
    }

    /**
     * 健康检查接口
     */
    @GetMapping("/health")
    @Operation(summary = "健康检查", description = "检查服务和数据库连接状态")
    public ResponseEntity<Map<String, Object>> health() {
        
        Map<String, Object> response = new HashMap<>();
        
        try {
            // 测试从库连接
            long slaveCount = userServiceImpl.countUsers();
            response.put("slave", "正常，用户数量：" + slaveCount);
            
            // 测试主库连接（通过查询一个用户）
            User masterUser = userService.getById(1L);
            response.put("master", masterUser != null ? "正常" : "无数据");
            
            response.put("code", 200);
            response.put("message", "服务正常");
            response.put("timestamp", LocalDateTime.now());
            
        } catch (Exception e) {
            response.put("code", 500);
            response.put("message", "服务异常：" + e.getMessage());
            response.put("timestamp", LocalDateTime.now());
        }
        
        return ResponseEntity.ok(response);
    }
}
